package main

import (
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"io/ioutil"
	"net/http"
	"reflect"
	"time"
)

func BodyToMap(body []byte) map[string]string {
	byteData := body                            //将body的[]byte数据存储起来
	var jsonData map[string]interface{}         //定义一个map[string]用来转换成json
	err1 := json.Unmarshal(byteData, &jsonData) //将body存储到map[string]中进行json转换
	if err1 != nil {
		fmt.Println("解析JSON失败:", err1)
		return map[string]string{}
	}
	responseData := jsonData
	fmt.Println("BodyToMap responseData:", responseData) //是一个 map[xxx:xxx]
	//分离map
	fmt.Println("responseData type:", reflect.TypeOf(responseData)) //查看数据类型
	// 将 map[string]interface{} 类型转换为 map[string]string 类型
	dataMap := make(map[string]string)

	fmt.Println("dataMap data:", dataMap)
	fmt.Println("dataMap type:", reflect.TypeOf(dataMap)) //查看数据类型

	//添加数据
	value1 := responseData["username"]    //map[string]interface{} 转成interface{}
	dataMap["username"] = value1.(string) //从interface{}转成string(过程运用的是类型断言)

	value2 := responseData["password"]    //map[string]interface{} 转成interface{}
	dataMap["password"] = value2.(string) //从interface{}转成string(过程运用的是类型断言)

	return dataMap
}

type MyClaims struct {
	UserName string `json:"username"`
	PassWord string `json:"password"`
	jwt.StandardClaims
}

func CreateToken(username string, password string) (string, error) {
	mySigningKey := []byte("chentianyu")
	c := MyClaims{
		UserName: username,
		PassWord: password,
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix(),           //当前生效
			ExpiresAt: time.Now().Unix() + 60*60*2, //俩小时过期
			Issuer:    username,
		},
	}
	t := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	s, err := t.SignedString(mySigningKey)
	return s, err
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "hello World!")
}

func userLoginTokenHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		body, _ := ioutil.ReadAll(r.Body) //读取post请求中body的值
		defer r.Body.Close()
		//fmt.Println("body:", body)
		data := BodyToMap(body)
		fmt.Println("myData:", data["username"], "password:", data["password"])
		username := data["username"]
		password := data["password"]
		//fmt.Fprintf(w, data["username"])
		s, _ := CreateToken(username, password)
		fmt.Fprintf(w, s)
	}
}

func main() {
	//创建一个处理跨域请求的处理器函数
	corsHandler := func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// 设置允许跨域的域名
			w.Header().Set("Access-Control-Allow-Origin", "*")
			// 允许的请求方法
			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
			// 允许的请求头
			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
			// 如果是预检请求，直接返回
			if r.Method == "OPTIONS" {
				return
			}
			h.ServeHTTP(w, r)
		})
	}

	http.Handle("/", corsHandler(http.HandlerFunc(handler)))
	http.Handle("/login", corsHandler(http.HandlerFunc(userLoginTokenHandler)))

	http.ListenAndServe(":8788", nil)
}
